﻿using System;
using System.Data;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;

using FRL.DebtChased.Repository;
using FRL.DebtChased.Repository.PartModels;
using FRL.DebtChased.Repository.ViewModels;
using FRL.DebtChased.WebServices;

namespace FRL.DebtChased.Website
{

	/////////////////////////////////////////////////////////////////////
	// Declaration of MySession class

	public class MySession
	{

		/////////////////////////////////////////////////////////////////
		// Constants

		private const String keyName = "_currentUser";

		/////////////////////////////////////////////////////////////
		// These attributes are for managing an active session for a logged in client or admin

		private int m_iUserID;
		public int UserID { get { return m_iUserID; } }

		private int m_iClientContactId;
		public int ClientContactID { get { return m_iClientContactId; } }

		private string m_strFullName;
		public string FullName { get { return m_strFullName; } }

		private int m_iClientID;
		public int ClientID { get { return m_iClientID; } }

		private string m_strClientName;
		public string ClientName { get { return m_strClientName; } }

		private Definitions.eRoles m_Roles;
		public Definitions.eRoles Roles { get { return m_Roles; } }

		/////////////////////////////////////////////////////////////
		// Models used in dashboard

		private Dictionary<string, BasePartModel> m_partModelMap = null;

		/////////////////////////////////////////////////////////////
		// Debt Chase Account List

		private List<int> m_ExtraAccountIdsForChaseSession = new List<int>();
		public List<int> ExtraAccountIdsForChaseSession
		{
			get { return ExtraAccountIdsForChaseSession; }
		}

		/////////////////////////////////////////////////////////////
		// Handover Parameters

		private string m_strHandoverTarget;

		private int m_iHandoverId;

		/////////////////////////////////////////////////////////////
		// Client Id

		private int m_iContextClientId;
		public int ContextClientId
		{
			get { return m_iContextClientId; }
			set { m_iContextClientId = value; }
		}

		/////////////////////////////////////////////////////////////////
		// Construction

		public MySession()
		{

			// Initialize member variables
			this.Scrub();

		}

		/////////////////////////////////////////////////////////////////
		// Operations

		public void SetTimeout(int iSessionTimeoutMins)
		{

			// Update the session timeout
			HttpContext.Current.Session.Timeout = iSessionTimeoutMins;

		}

		public void LogOn( DebtChasedEntities ent, User user )
		{

			// Update my session with the new credentials
			this.m_iUserID = user.UserId;
			this.m_Roles = user.Roles;
			this.m_strFullName = User.GetFullName(ent, this.m_iUserID);
			if ((this.m_Roles & (Definitions.AnyClientUserRole)) != 0)
			{

				// Get client id, client contact id, and name
				Client.UserIdToClient(
					ent, 
					this.m_iUserID, 
					ref m_iClientID, 
					ref m_iClientContactId,
					ref m_strClientName
				);

			}
			else
			{
				this.m_iClientID = 0;
				this.m_strClientName = null;
			}
			this.m_partModelMap = new Dictionary<string,BasePartModel>();

		}

		public void Scrub()
		{

			// Initialize member variables
			this.m_iUserID = 0;
			m_Roles = Definitions.eRoles.NotSet;
			m_strFullName = null;
			m_iClientID = 0;
			m_iClientContactId = 0;
			m_strClientName = null;

			// Clear the models
			this.m_partModelMap = null;

			// Clear the handover
			m_iHandoverId = 0;
			m_strHandoverTarget = null;

		}

		/////////////////////////////////////////////////////////////////
		// Static Operations - Testing session and user-type

		public static MySession BindMySession()
		{

			// Get the session variable
			MySession Ftmp = HttpContext.Current.Session[keyName] as MySession;

			// If not found...
			if (Ftmp == null)
			{

				// Create session object
				Ftmp = new MySession();

				// Update HTTP context
				HttpContext.Current.Session[keyName] = Ftmp;
				HttpContext.Current.Session.Timeout = 5 * 24 * 60; // 5 days

			}

			// Return variable
			return Ftmp;

		}

		public static bool IsUserLoggedIn()
		{

			// Return true is a user is logged on, otherwise
			// return false, but whatever happens, do not create an
			// unecessary session object

			// Get the session variable
			MySession Ftmp = HttpContext.Current.Session[keyName] as MySession;

			// shortcuts
			if (Ftmp == null)
				return false;

			// User logged on is UserId!=0
			return (Ftmp.UserID != 0);

		}

		public bool ContainsRole(Definitions.eRoles Roles)
		{

			// Declare return variable
			return Definitions.Contains(Roles, m_Roles);

		}

		/////////////////////////////////////////////////////////////
		// Operations

		public void LoadingPage(string strPagePath)
		{

			// Loose unused session objects
			if (!strPagePath.EndsWith("Dashboard.aspx", StringComparison.CurrentCultureIgnoreCase))
			{

				// Scrub the session state for the web parts					
				this.ClearPartModels();

			}

		}

		/////////////////////////////////////////////////////////////
		// Operations - Part Models

		public void AddPartModel(string strUniqueId, BasePartModel model)
		{

			// Remove existing model from dictionary
			m_partModelMap.Remove(strUniqueId);

			// Add to the dictionary
			m_partModelMap.Add(strUniqueId, model);

		}

		public BasePartModel FindPartModel(string strUniqueId)
		{

			// Search the model dictionary
			return (from m in m_partModelMap where (m.Key == strUniqueId) select m.Value).FirstOrDefault();

		}

		public void ClearPartModel(string strUniqueId)
		{

			// Remove existing model from dictionary
			if(m_partModelMap!=null)
				m_partModelMap.Remove(strUniqueId);

		}

		public void ClearPartModels()
		{

			// Remove all existing models from dictionary
			if(m_partModelMap!=null)
				m_partModelMap.Clear();

		}

		/////////////////////////////////////////////////////////////
		// Operations - The extra account ids for chase session

		public void ClearDebtChaseAccountList()
		{

			// Reset the list and the offset
			m_ExtraAccountIdsForChaseSession.Clear();

		}

		public void UniqueAddExtraAccountIdsForChaseSession(GridView gv, string strCheckBoxColumn)
		{

			// Navigate through each row in the GridView for checkbox items
			foreach (GridViewRow row in gv.Rows)
			{

				// Get the checkbox
				CheckBox checkBox = (CheckBox)row.FindControl(strCheckBoxColumn);
				if (checkBox.Checked)
				{

					// Convert argument to id
					int iAccountId = int.Parse(gv.DataKeys[row.RowIndex].Value.ToString());

					// Add to debt-chase list
					if (
						(iAccountId != 0)
						&&
						(!m_ExtraAccountIdsForChaseSession.Contains(iAccountId))
					)
						m_ExtraAccountIdsForChaseSession.Add(iAccountId);

				}

			}

		}

		/////////////////////////////////////////////////////////////
		// Operations - Handover Parameters

		public void SetHandover( string strTarget, int iId )
		{

			// Set member variables
			m_strHandoverTarget = strTarget;
			m_iHandoverId = iId;

		}

		public int? PullHandover( Page page )
		{

			// Shortcuts
			if (string.IsNullOrEmpty(m_strHandoverTarget))
				return null;

			// Declare return variable
			int? iFtmp = null;

			// Check the page
			if (page.AppRelativeVirtualPath.Contains(m_strHandoverTarget))
			{

				// Update return variable
				iFtmp = m_iHandoverId;

			}

			// Reset the handover
			m_iHandoverId = 0;
			m_strHandoverTarget = null;

			// Return variable
			return iFtmp;

		}

		/////////////////////////////////////////////////////////////
		// Operations - Transport Objects

		public void LoadUserSessionTransport( UserSessionTransport sessionTransport )
		{

			// Set member variables
			sessionTransport.UserId = this.UserID;
			sessionTransport.UserDescription = this.m_strFullName;
			sessionTransport.Roles = (int)this.Roles;
			sessionTransport.ClientId = this.m_iClientID;
			sessionTransport.ClientContactId = this.m_iClientContactId;

		}

		/////////////////////////////////////////////////////////////
		// Operations - Dummy Data

#if DEBUG
		public void SetDummyClient()
		{

			// Log on as client-admin
			using (DebtChasedEntities ent = new DebtChasedEntities())
			{

				// Load the user
				FRL.DebtChased.Repository.User user = FRL.DebtChased.Repository.User.GetUserByUsername(ent, "bmcgee");
				this.LogOn(ent, user);

			}
		}
#endif // #if DEBUG

#if DEBUG
		public void SetDummySysAdmin()
		{
			this.m_iUserID = 1;
			this.m_strFullName = "Richard Salmon";
			this.m_Roles = Definitions.eRoles.FIN_SYSADMIN;
		}
#endif // #if DEBUG

	}

}